home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_se / e_feature.e < prev    next >
Text File  |  2000-03-25  |  11KB  |  384 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. deferred class E_FEATURE
  17.    --
  18.    -- For all possible Features : procedure, function, attribute,
  19.    -- constants, once procedure, once function, ...
  20.    --
  21.  
  22. inherit GLOBALS;
  23.  
  24. feature
  25.  
  26.    base_class: BASE_CLASS;
  27.          -- The class where the feature is really written.
  28.  
  29.    names: FEATURE_NAME_LIST;
  30.          -- All the names of the feature.
  31.  
  32.    arguments: FORMAL_ARG_LIST is
  33.          -- Arguments if any.
  34.       deferred
  35.       end;
  36.  
  37.    result_type: TYPE is
  38.          -- Result type if any.
  39.       deferred
  40.       end;
  41.  
  42.    header_comment: COMMENT;
  43.          -- Header comment for a routine or following comment for
  44.          -- an attribute.
  45.  
  46.    obsolete_mark: MANIFEST_STRING is
  47.          -- The `obsolete' mark if any.
  48.       deferred
  49.       end;
  50.  
  51.    require_assertion: E_REQUIRE is
  52.          -- Not Void if any.
  53.       deferred
  54.       end;
  55.  
  56.    ensure_assertion: E_ENSURE is
  57.          -- Not Void if any.
  58.       deferred
  59.       end;
  60.  
  61.    clients: CLIENT_LIST;
  62.          -- Authorized clients list of the corresponding feature
  63.          -- clause in the base definition class.
  64.  
  65.    is_deferred: BOOLEAN is
  66.          -- Is it a deferred feature ?
  67.       deferred
  68.       end;
  69.  
  70.    frozen mapping_c_name_in(str: STRING) is
  71.      -- *** VIRER ??? ***
  72.       do
  73.          base_class.mapping_c_in(str);
  74.          str.append(first_name.to_key);
  75.       end;
  76.  
  77.    frozen mapping_c_name is
  78.       local
  79.          s: STRING;
  80.       do
  81.          s := "    ";
  82.          s.clear;
  83.          mapping_c_name_in(s);
  84.          cpp.put_string(s);
  85.       end;
  86.  
  87.    frozen base_class_name: CLASS_NAME is
  88.          -- Name of the class where the feature is really written.
  89.       do
  90.          Result := base_class.name;
  91.       end;
  92.  
  93.    frozen first_name: FEATURE_NAME is
  94.       do
  95.          Result := names.first;
  96.       ensure
  97.          Result /= void
  98.       end;
  99.  
  100.    frozen start_position: POSITION is
  101.       do
  102.          Result := first_name.start_position;
  103.       end;
  104.  
  105.    to_run_feature(t: TYPE; fn: FEATURE_NAME): RUN_FEATURE is
  106.          -- If possible, gives the checked runnable feature for `t'.
  107.          -- Note: corresponding run_class dictionary is updated
  108.          --       with this new feature.
  109.       require
  110.          t.is_run_type;
  111.          fn /= Void;
  112.       deferred
  113.       ensure
  114.          Result /= Void implies t.run_class.at(fn) = Result;
  115.          Result = Void implies nb_errors > 0
  116.       end;
  117.  
  118.    can_hide(other: E_FEATURE; rc: RUN_CLASS): BOOLEAN is
  119.          -- True when headings of Current can be hide with
  120.          -- heading of `other' in `rc'.
  121.       require
  122.          Current /= other;
  123.       do
  124.          if result_type /= other.result_type then
  125.             if result_type = Void or else other.result_type = Void then
  126.                eh.add_position(other.start_position);
  127.                error(start_position,em_ohrbnto);
  128.             end;
  129.          end;
  130.          if arguments /= other.arguments then
  131.             if arguments = Void or else other.arguments = Void then
  132.                eh.add_position(other.start_position);
  133.                error(start_position,em_ohabnto);
  134.             elseif arguments.count /= other.arguments.count then
  135.                eh.add_position(other.start_position);
  136.                error(start_position,em_ina);
  137.             end;
  138.          end;
  139.          if nb_errors = 0 then
  140.             if result_type /= Void then
  141.                if not result_type.is_a_in(other.result_type,rc) then
  142.                   eh.append(em_chtfi);
  143.                   eh.append(rc.current_type.run_time_mark);
  144.                   eh.append(fz_dot);
  145.                   eh.print_as_error;
  146.                end;
  147.             end;
  148.          end;
  149.          if nb_errors = 0 then
  150.             if arguments /= Void then
  151.                if not arguments.is_a_in(other.arguments,rc) then
  152.                   eh.add_position(other.start_position);
  153.                   eh.add_position(start_position)
  154.                   eh.append(em_chtfi);
  155.                   eh.append(rc.current_type.run_time_mark);
  156.                   eh.append(fz_dot);
  157.                   eh.print_as_error;
  158.                end;
  159.             end;
  160.          end;
  161.          Result := nb_errors = 0;
  162.          if Result then
  163.             merge_header_comments(other);
  164.          end;
  165.       end;
  166.  
  167.    frozen check_obsolete(caller: POSITION) is
  168.       require
  169.          not caller.is_unknown
  170.       do
  171.          if obsolete_mark /= Void then
  172.             if not small_eiffel.short_flag then
  173.                eh.add_position(caller);
  174.                eh.append("This feature is obsolete :%N");
  175.                eh.append(obsolete_mark.to_string);
  176.                eh.add_position(start_position);
  177.                eh.print_as_warning;
  178.             end
  179.          end;
  180.       end;
  181.  
  182.    set_header_comment(hc: like header_comment) is
  183.       do
  184.          header_comment := hc;
  185.       end;
  186.  
  187.    pretty_print is
  188.       require
  189.          fmt.indent_level = 1;
  190.       deferred
  191.       ensure
  192.          fmt.indent_level = 1;
  193.       end;
  194.  
  195.    frozen pretty_print_profile is
  196.       do
  197.          pretty_print_names;
  198.          fmt.set_indent_level(2);
  199.          pretty_print_arguments;
  200.          fmt.set_indent_level(3);
  201.          if result_type /= Void then
  202.             fmt.put_string(": ");
  203.             result_type.pretty_print;
  204.          end;
  205.       end;
  206.  
  207. feature {PARENT_LIST}
  208.  
  209.    frozen is_not_mergeable_with(other: E_FEATURE): BOOLEAN is
  210.          -- True when `Current' and `other' are clearly not mergeable 
  211.          -- because of a different number of arguments or result.
  212.       require
  213.          Current /= other;
  214.          eh.is_empty
  215.       do
  216.          if result_type = Void then
  217.             Result := other.result_type /= Void;
  218.          else
  219.             Result := other.result_type = Void;
  220.          end;
  221.          if Result then
  222.             eh.append(em_ohrbnto);
  223.          else
  224.             if arguments = Void then
  225.                Result := other.arguments /= Void;
  226.             else
  227.                Result := other.arguments = Void;
  228.             end;
  229.             if Result then
  230.                eh.append(em_ohabnto);
  231.             elseif arguments = Void then
  232.             elseif arguments.count /= other.arguments.count then
  233.                eh.append(em_ina);
  234.                Result := true;
  235.             end;
  236.          end;
  237.          merge_header_comments(other);
  238.       ensure
  239.          Result = not eh.is_empty
  240.       end;
  241.  
  242. feature {PARENT}
  243.  
  244.    frozen try_to_undefine(fn: FEATURE_NAME; bc: BASE_CLASS):
  245.       DEFERRED_ROUTINE is
  246.          -- Compute the corresponding deferred feature for `Current'.
  247.          -- This occurs for example when `bc' has an undefine clause 
  248.          -- for `fn' which refer to `Current'.
  249.          -- The Result is never Void because `fatal_error' may be called. 
  250.          -- Also check VDUS.
  251.       require
  252.          fn /= Void;
  253.          bc.name.is_subclass_of(base_class_name)
  254.       local
  255.          fn2: FEATURE_NAME;
  256.       do
  257.          -- For (VDUS) :
  258.          eh.add_position(fn.start_position);
  259.          fn2 :=  names.feature_name(fn.to_key);
  260.          if fn2 /= Void then
  261.             fn2.undefine_in(bc);
  262.          end;
  263.          eh.cancel;
  264.          --
  265.          Result := try_to_undefine_aux(fn,bc);
  266.          if Result /= Void then
  267.             Result.set_clients(clients);
  268.             merge_header_comments(Result);
  269.          else
  270.             bc.fatal_undefine(fn);
  271.          end;
  272.       ensure
  273.          Result /= Void
  274.       end;
  275.  
  276. feature {FEATURE_CLAUSE,E_FEATURE}
  277.  
  278.    set_clients(c: like clients) is
  279.       require
  280.          c /= Void;
  281.       do
  282.          clients := c;
  283.       ensure
  284.          clients = c;
  285.       end;
  286.  
  287. feature {FEATURE_CLAUSE}
  288.  
  289.    add_into(fd: DICTIONARY[E_FEATURE,STRING]) is
  290.          -- Also check for multiple definitions.
  291.       local
  292.          i: INTEGER;
  293.          fn: FEATURE_NAME;
  294.       do
  295.          base_class := names.item(1).start_position.base_class;
  296.          from
  297.             i := 1;
  298.          until
  299.             i > names.count
  300.          loop
  301.             fn := names.item(i);
  302.             if fd.has(fn.to_key) then
  303.                fn := fd.at(fn.to_key).first_name;
  304.                eh.add_position(fn.start_position);
  305.                eh.add_position(names.item(i).start_position);
  306.                eh.append("Double definition of feature ");
  307.                eh.append(fn.to_string);
  308.                eh.append(fz_dot);
  309.                eh.print_as_error;
  310.             else
  311.                fd.put(Current,fn.to_key);
  312.             end;
  313.             i := i + 1;
  314.          end;
  315.       end;
  316.  
  317. feature {NONE}
  318.  
  319.    frozen pretty_print_names is
  320.          -- Print only the names of the feature.
  321.       local
  322.          i: INTEGER;
  323.       do
  324.          from
  325.             i := 1;
  326.             names.item(i).declaration_pretty_print;
  327.             i := i + 1;
  328.          until
  329.             i > names.count
  330.          loop
  331.             fmt.put_string(", ");
  332.             names.item(i).declaration_pretty_print;
  333.             i := i + 1;
  334.          end;
  335.       end;
  336.  
  337.    pretty_print_arguments is
  338.       deferred
  339.       end;
  340.  
  341.    make_e_feature(n: like names) is
  342.       require
  343.          n.count >= 1;
  344.       do
  345.          names := n;
  346.       ensure
  347.          names = n
  348.       end;
  349.  
  350.    try_to_undefine_aux(fn: FEATURE_NAME;
  351.                        bc: BASE_CLASS): DEFERRED_ROUTINE is
  352.       require
  353.          fn /= Void;
  354.          bc /= Void
  355.       deferred
  356.       end;
  357.  
  358.    frozen merge_header_comments(other: E_FEATURE) is
  359.          -- Falling down of the `header_comment' for command short.
  360.       do
  361.          if small_eiffel.short_flag then
  362.             if header_comment = Void then
  363.                header_comment := other.header_comment;
  364.             elseif other.header_comment = Void then
  365.                other.set_header_comment(header_comment);
  366.             end;
  367.          end;
  368.       end;
  369.  
  370.    em_chtfi: STRING is " Cannot inherit these features in ";
  371.  
  372.    em_ohrbnto: STRING is "One has Result but not the other.";
  373.  
  374.    em_ohabnto: STRING is "One has argument(s) but not the other.";
  375.  
  376.    em_ina: STRING is "Incompatible number of arguments.";
  377.  
  378. invariant
  379.  
  380.    names /= Void;
  381.  
  382. end -- E_FEATURE
  383.  
  384.